package work.vcloud.baseinfo.service.impl;

import com.sun.management.OperatingSystemMXBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import work.vcloud.baseinfo.exception.BaseException;
import work.vcloud.baseinfo.service.intfc.HardWareMonitorService;


import javax.annotation.PostConstruct;
import java.lang.management.ManagementFactory;
import java.util.*;

/**
 * 硬件监控
 */
@Service
public class HardWareMonitorServiceImpl implements HardWareMonitorService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public static void main(String[] args) {
        long time = new Date().getTime();
        int pageNo = (int) ((time / 1000) & 1);
        int limit = 15;
        int offset = pageNo * limit;
        System.out.println(offset);
    }

    //记录的最大长度
    public final static int RATE_QUEUE_SIZE = 10;
    //cpu占用率
    private Queue cpuRateQueue = new LinkedList();
    //内存占用率
    private Queue memoryRateQueue = new LinkedList();

    @SuppressWarnings("restriction")
    OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();

    @PostConstruct
    public void record() {
        new Thread(() -> {
            //初始化
            for (int i = 0; i < RATE_QUEUE_SIZE; i++) {
                cpuRateQueue.offer(new TimeRate(0d));
                memoryRateQueue.offer(new TimeRate(0d));
            }
            while (true) {
                try {
                    //System.out.println("开始记录");
                    double cpuRate = 0;
                    while (true) {
                        Thread.sleep(1000);
                        cpuRate = getCPULoad();
                        if (cpuRate > 0.0 && cpuRate < 1.0)
                            break;
                    }
                    //double cpuRate = getCPURate();
                    double memoryRate = getMemoryRate();

                    if (!cpuRateQueue.offer(new TimeRate(cpuRate))) {
                        logger.info("cpu占用率添加到队列失败！");
                    }
                    if (!memoryRateQueue.offer(new TimeRate(memoryRate))) {
                        logger.info("内存占用率添加到队列失败！");
                    }
                    while (cpuRateQueue.size() > RATE_QUEUE_SIZE) {
                        cpuRateQueue.poll();
                    }
                    while (memoryRateQueue.size() > RATE_QUEUE_SIZE) {
                        memoryRateQueue.poll();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 获取cpu负载
     *
     * @return
     */
    private double getCPULoad() {
        double proLoad = osBean.getProcessCpuLoad();
        double sysLoad = osBean.getSystemCpuLoad();
        //System.out.printf("  --%s Load(%d cores)-- Process: %.5f, System: %.5f %n", osBean.getName(), osBean.getAvailableProcessors(), proLoad, sysLoad);
        return (proLoad + sysLoad);
    }

    /**
     * 获取内存占用率
     *
     * @return
     */
    public double getMemoryRate() {
        double rate = (double) osBean.getFreePhysicalMemorySize() / osBean.getTotalPhysicalMemorySize();
        return 1 - rate;
    }

    /**
     * 获取cpu占用率（最后几次）
     *
     * @param lastCount
     * @return
     */
    @Override
    public TimeRate[] getCPURateArray(int lastCount) {
        if (lastCount > RATE_QUEUE_SIZE) {
            throw new BaseException("超过最大长度！");
        }
        Object[] objects = cpuRateQueue.toArray();
        TimeRate[] array = new TimeRate[objects.length];
        for (int i = 0; i < objects.length; i++) {
            array[i] = (TimeRate) objects[i];
        }
        array = Arrays.copyOfRange(array, array.length - lastCount, array.length);
        return array;
    }

    /**
     * 获取内存占用率（最后几次）
     *
     * @param lastCount
     * @return
     */
    @Override
    public TimeRate[] getMemoryRateArray(int lastCount) {
        if (lastCount > RATE_QUEUE_SIZE) {
            throw new BaseException("超过最大长度！");
        }
        Object[] objects = memoryRateQueue.toArray();
        TimeRate[] array = new TimeRate[objects.length];
        for (int i = 0; i < objects.length; i++) {
            array[i] = (TimeRate) objects[i];
        }
        array = Arrays.copyOfRange(array, array.length - lastCount, array.length);
        return array;
    }

    public class TimeRate {
        private Date date;
        private double rate;

        TimeRate(double rate) {
            this.date = new Date();
            this.rate = rate;
        }

        public Date getDate() {
            return date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

        public double getRate() {
            return rate;
        }

        public void setRate(double rate) {
            this.rate = rate;
        }
    }
}

